home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 16 / AMIGAplus Sonderheft 16 (1998)(ICP)(DE)[!].iso / pd / anwendungen / xpk_source / prefs / xpkmaster.c < prev    next >
C/C++ Source or Header  |  1998-08-27  |  42KB  |  1,527 lines

  1. #define NAME        "XpkMaster"
  2. #define DISTRIBUTION    "(Freeware) "
  3. #define REVISION    "30"
  4. #define SDI_ENDCODE
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        XpkMaster
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    Prefs program for XpkMaster
  12.     Compileropts:    -
  13.     Linkeropts:    -l amiga
  14.     ToDo:        speed up refresh, by flags based choose of to
  15.             refresh gadgets
  16.  
  17.  1.0   10.11.96 : first Version, incomplete, started to form GUI
  18.  1.1   11.11.96 : corrected, added the code a bit
  19.  1.2   16.11.96 : some more stuff
  20.  1.3   17.11.96 : completed GUI
  21.  1.4   20.11.96 : added more functions
  22.  1.5   21.11.96 : added icon creation, corrected some stuff
  23.  1.6   23.11.96 : corrected some stuff
  24.  1.7   24.11.96 : added loading and cleaned up source
  25.  1.8   30.11.96 : fixed some errors, still working incorrect
  26.  1.9   01.12.96 : and again some bugfixes
  27.  1.10  07.12.96 : correct Default dir in asl request and wb call
  28.  1.11  12.12.96 : fixed crash problem, when called by project icon with
  29.      ACTION=EDIT
  30.  1.12  13.12.96 : made the window a bit smaller for larger texts and fonts
  31.  1.13  14.12.96 : changed the Prefs include XPKM -> XPKT, XPKD -> XPKM,
  32.      other member prefixes
  33.  1.14  20.12.96 : fixed Enforcer hit (I finally have a MMU :-) and little
  34.     error
  35.  1.15  25.12.96 : corrected List handling
  36.  1.16  26.12.96 : once again changed xpkprefs.h -> now should be last time,
  37.      because I wrote the prefs support for master library
  38.  1.17  29.12.96 : fixed bug with XPKM flags
  39.  1.18  09.01.97 : changed default flags
  40.  1.19  11.01.97 : splitted master library and prefs catalog
  41.  1.20  01.03.97 : changed XpkMainPrefs structure a bit
  42.  1.21  07.03.97 : recompiled, because of structures additions
  43.  1.22  08.03.97 : fixed a crash causing typo error
  44.  1.23  02.04.97 : changed XpkTypeData structure
  45.  1.24  03.04.97 : fixed error
  46.  1.25  04.04.97 : fixed error in texts
  47.  1.26  10.04.97 : default entry now 1 and not 0
  48.  1.27  18.05.97 : corrected internal string
  49.  1.28  31.05.97 : SDI_locale changed
  50.  1.29  17.06.97 : now prints entry name for illegal entry
  51.  1.30  18.06.97 : library name file requester got wrong value
  52. */
  53.  
  54. #include <proto/exec.h>
  55. #include <proto/intuition.h>
  56. #include <proto/dos.h>
  57. #include <proto/icon.h>
  58. #include <proto/gadtools.h>
  59. #include <proto/graphics.h>
  60. #include <proto/asl.h>
  61. #include <proto/iffparse.h>
  62. #include <xpk/xpkprefs.h>
  63. #include <clib/alib_protos.h>
  64. #include <intuition/gadgetclass.h>
  65. #include <workbench/startup.h>
  66. #include <prefs/prefhdr.h>
  67. #include <exec/memory.h>
  68. #include "SDI_defines.h"
  69. #define SDI_LOCALE_NO_STRUCTS
  70. #include "SDI_locale.c"
  71. #include "SDI_ASM_STD_protos.h"
  72.  
  73. /* ------------------ defines and structures --------------------------- */
  74.  
  75. #define PARAM    "FROM,EDIT/S,USE/S,SAVE/S,PUBSCREEN/K"
  76.  
  77. #define GADGET(a)     ((struct Gadget *) a->IAddress)
  78. #define STRINF(a)    ((struct StringInfo *) (a->SpecialInfo))
  79. #define    DEFNODE(a)    ((struct PackerNode *) ((a)->ld_List.lh_Head))
  80.  
  81. #define PicSize        509    /* size of the icon */
  82.  
  83. enum {
  84. STRING_TypeName = 100,    LISTVIEW,        BUTTON_New,
  85. BUTTON_Delete,        BUTTON_Up,        BUTTON_Down,
  86. STRING_NamePatt,    STRING_FilePatt,    STRING_LibraryName,
  87. GETIMAGE,        INTEGER_Mode,        INTEGER_ChunkSize,
  88. CYCLE,            INTEGER_TimeOut,    CHECKBOX_XFD,
  89. CHECKBOX_EXT,        CHECKBOX_Password,    BUTTON_Save,
  90. BUTTON_Use,        BUTTON_Chancel
  91. };
  92.  
  93. #define PREF_VERSION    0    /* version of prefs I can work with */
  94.  
  95. #define    DEFAULT_NODE    100
  96. #define PACKER_NODE    101
  97.  
  98. #define DEF_TIMEOUT    120
  99. #define DEF_XPKM_FLAGS    (XPKM_AutoPassword | XPKM_UseExternals)
  100. #define DEF_CYCLE    2 /* XTD_ReturnError */
  101.  
  102. /* window style defines */
  103. #define SEPARATE_SAME    2
  104. #define SEPARATE_DIFF    5
  105. #define SEPARATE_BORD    5
  106.  
  107. #define TypeSIZE    49
  108. #define NamePattSIZE    49
  109. #define FilePattSIZE    99
  110.  
  111. struct PackerNode {
  112.   struct Node        pn_Node;
  113.   ULONG            pn_StdID;
  114.   UWORD            pad;    /* always StdID finished with 0 byte */
  115.   UWORD            pn_Mode;
  116.   ULONG            pn_ChunkSize;
  117.   ULONG            pn_Cycle;
  118.   UBYTE            pn_TypeName[TypeSIZE+1];
  119.   UBYTE            pn_NamePattern[NamePattSIZE+1];
  120.   UBYTE            pn_FilePattern[FilePattSIZE+1];
  121. };
  122.  
  123. struct ListData {
  124.   struct List    ld_List;
  125.   struct PackerNode    *ld_curNode;
  126.   ULONG            ld_entries;
  127.   ULONG            ld_curNumber;
  128. };
  129.  
  130. struct Args {
  131.   STRPTR from;
  132.   ULONG     edit;
  133.   ULONG     use;
  134.   ULONG  save;
  135.   STRPTR pubscreen;
  136.   ULONG     createicons;
  137. };
  138.  
  139. /* ----------------------------- Strings ------------------------------- */
  140.  
  141. #define TEXT_START_MENUMAIN    0
  142. #define NUMBER_MENUMAIN        11
  143.  
  144. enum {
  145. TEXT_WINDOW_TITLE = NUMBER_MENUMAIN,        TEXT_ENTRY_DEFAULT,
  146. TEXT_ENTRY_NEW,        TEXT_SELECT_LIBRARY,    TEXT_LOAD_PREFERENCES,
  147. TEXT_SAVE_PREFERENCES,    TEXT_TITLE_ERR_REQUEST,    TEXT_ERROR_FILEACCESS,
  148. TEXT_LIB_REQUIRED,    TEXT_VERSION_TO_HIGH,    TEXT_ERROR_FILEPROCESS,
  149. TEXT_ILLEGAL_ENTRY,    TEXT_NO_WINDOW,        GADGS_ERR_REQUEST,
  150. GADG_Save,        GADG_Use,        GADG_Cancel,
  151. GADG_Use_XFD,        GADG_Use_Externals,    GADG_AutoPassword,
  152. GADG_Timeout,        GADG_New,        GADG_Delete,
  153. GADG_Up,        GADG_Down,        GADG_Name_Pattern,
  154. GADG_File_Pattern,    GADG_Library_Name,    GADG_Mode,
  155. GADG_ChunkSize,        GADG_PackMode,        TEXT_START_SLIDER
  156. };
  157.  
  158. #define TEXT_START_OTHER    (NUMBER_MENUMAIN)
  159. #define TEXT_START_GADGET    (GADG_Save)
  160.  
  161. #define NUMBER_OTHER        (TEXT_START_GADGET-TEXT_START_OTHER)
  162. #define NUMBER_GADGET        (TEXT_START_SLIDER-TEXT_START_GADGET)
  163. #define NUMBER_SLIDER        3
  164.  
  165. struct SDI_SetLocale initloc[] = {
  166. { 400, NUMBER_MENUMAIN, TEXT_START_MENUMAIN}, /* Main-Menutexts */
  167. { 420, NUMBER_OTHER,    TEXT_START_OTHER},    /* all other texts */
  168. { 450, NUMBER_SLIDER,   TEXT_START_SLIDER},   /* Slider texts */
  169. { 460, NUMBER_GADGET,   TEXT_START_GADGET},   /* Gadgettexts */
  170. {   0, 0, 0},                      /* Ende */
  171. };
  172.  
  173. STRPTR text[] =
  174. {
  175. "Project",
  176. "O\0Open...",
  177. "M\0Load Add...",
  178. "A\0Save As...",
  179. "Q\0Quit",
  180. "Edit",
  181. "D\0Reset To Defaults",
  182. "L\0Last Saved",
  183. "R\0Restore",
  184. "Settings",
  185. "I\0Create Icons?",
  186. "XpkMaster Preferences",    /* the window title */
  187. "«default»",            /* the default pack mode */
  188. "«new»",
  189. "Select xpk or xex library",
  190. "Load XpkMaster preferences",
  191. "Save XpkMaster preferences",
  192. "Program Error",
  193. "Error accessing file\n%s\n%s",
  194. "Requires %s V%ld",
  195. "Prefs file version to high,\nloaded data may be incomplete.",
  196. "Error processing IFF file",
  197. "%s of entry %ld (%s)\nis illegal, cannot save.",
  198. "Could not open window,\nthe used font is too large.",
  199. "OK",
  200. "Save",
  201. "Use",
  202. "Cancel",
  203. "Use XFD",            /* the checkboxes */
  204. "Use XEX",
  205. "Auto password",
  206. "Timeout",            /* the timeout integer */
  207. "New",                /* the listview gadget */
  208. "Delete",
  209. "Up",
  210. "Down",
  211. "Name Pattern",
  212. "File Pattern",
  213. "Library Name",
  214. "Mode",
  215. "ChunkSize",
  216. "PackMode",
  217.  
  218. "pack xpk or xex",
  219. "do not pack",
  220. "return error",
  221. 0,
  222. };
  223.  
  224. STRPTR toolt[] =
  225. {
  226. "EDIT",
  227. "USE",
  228. "SAVE",
  229. "PUBSCREEN",
  230. "CREATEICONS",    /* YES || NO */
  231. "ACTION"
  232. };
  233.  
  234. /* ---------------------- protos and variables ------------------------- */
  235.  
  236. struct RDArgs        *rda        = 0;
  237. struct Library        *GadToolsBase    = 0,
  238.             *IconBase    = 0,
  239.             *UtilityBase    = 0,
  240.             *AslBase    = 0,
  241.             *IFFParseBase    = 0;
  242. struct LocaleBase    *LocaleBase    = 0;
  243. struct IntuitionBase    *IntuitionBase    = 0;
  244. struct GfxBase        *GfxBase    = 0;
  245. struct Screen        *Scr        = 0;
  246. APTR            VisualInfo    = 0;
  247. struct Window        *window        = 0;
  248. struct Gadget        *gadgList    = 0,
  249.             *gadgdata[12];
  250. /* List, NamePatt, FilePatt, LibraryName, GetImage, Mode, ChunkSize, Cycle,
  251. TimeOut, XFD, Extern, Pwd */
  252. struct Menu        *menus        = 0;
  253. struct DiskObject    *diskobject    = 0;
  254. ULONG            lock        = 0,
  255.             DosVersion    = 37,
  256.             TimeOut        = DEF_TIMEOUT,
  257.             XPKM_Flags    = DEF_XPKM_FLAGS;
  258. struct ListData        maindata    = {{(struct Node *) &maindata.ld_List.lh_Tail,
  259.      0, (struct Node *) &maindata.ld_List.lh_Head, NT_USER, 0}, 0, 0, 0};
  260. UBYTE            namestring[256];
  261. struct SDI_LocaleData    locdat = {"xpkmasterprefs.catalog", 1, 0,0,0,0};
  262.  
  263. #ifdef __MAXON__
  264. extern "C" void        wbmain(struct WBStartup *);
  265. void            main(void);
  266. #else
  267. void            wbmain(struct WBStartup *);
  268. void            main(int argc, char **argv);
  269. #endif
  270. void            Work(struct Args *);
  271. ULONG            SDIConvToUpper(STRPTR a);
  272.  
  273. void            CorrectAdr(APTR, APTR);
  274. void            CopyStrings(STRPTR, STRPTR, ULONG);
  275. void            CopyLibName(struct XpkTypeData *, struct PackerNode *);
  276. void            ReadXPKM(struct XpkMainPrefs *, struct ListData *);
  277. ULONG            ReadXPKT(struct XpkTypePrefs *, struct ListData *);
  278. ULONG            LoadFile(STRPTR, ULONG);
  279.  
  280. ULONG            CopyData(STRPTR, ULONG *, APTR, STRPTR *);
  281. ULONG            WriteXPKM(struct IFFHandle *);
  282. ULONG            WriteXPKT(struct IFFHandle *, struct PackerNode *, ULONG);
  283. ULONG            SaveFile(STRPTR, ULONG);
  284.  
  285. void            PrintError(STRPTR, ...);
  286. void            FileReq(void);
  287. ULONG            PrefsFileReq(STRPTR, ULONG, STRPTR);
  288. void            FreeListView(void);
  289. void            ResetListView(ULONG, struct ListData *);
  290. void            SetMainData(void);
  291. ULONG             DoWindow(void);
  292.  
  293. void            NewPackerList(struct ListData *);
  294. void            FreePackerList(struct ListData *);
  295. struct Node        *FindNode(struct List *, ULONG);
  296. struct PackerNode    *NewPackerNode(struct ListData *, STRPTR, struct PackerNode *, ULONG);
  297.  
  298. struct NewMenu NewMenus[] = {
  299.   NM_TITLE, (STRPTR) &text[TEXT_START_MENUMAIN],   0, 0, 0, 0,
  300.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+1], 0, 0, 0, 0,
  301.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+2], 0, 0, 0, 0,
  302.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+3], 0, 0, 0, 0,
  303.   NM_ITEM,  (STRPTR) NM_BARLABEL, 0, 0, 0, 0,
  304.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+4], 0, 0, 0, 0,
  305.   NM_TITLE, (STRPTR) &text[TEXT_START_MENUMAIN+5], 0, 0, 0, 0,
  306.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+6], 0, 0, 0, 0,
  307.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+7], 0, 0, 0, 0,
  308.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+8], 0, 0, 0, 0,
  309.   NM_TITLE, (STRPTR) &text[TEXT_START_MENUMAIN+9], 0, 0, 0, 0,
  310.   NM_ITEM,  (STRPTR) &text[TEXT_START_MENUMAIN+10], 0, MENUTOGGLE|CHECKIT, 0, 0,
  311.   NM_END,   0, 0, 0, 0, 0};
  312.  
  313. ULONG PicData[] = {
  314.   0xE3100001,0x00000000,0x0023000F,0x00360017,0x00050003,0x00010044,
  315.   0x39A00000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001,
  316.   0x049C004D,0x0CE00033,0x80F88000,0x00008000,0x00000000,0x00000000,
  317.   0x00000000,0x10000000,0x00000036,0x00170002,0x00024288,0x03000000,
  318.   0x00000000,0x00000004,0x00000000,0x00000001,0x00000000,0x07FF8000,
  319.   0x40000000,0x18006000,0x10000000,0x20FC1000,0x08000000,0x41020800,
  320.   0x0C000000,0x40820800,0x0C000000,0x40820800,0x0C000000,0x21040800,
  321.   0x0C000000,0x1E181000,0x0C000000,0x00602000,0x0C000000,0x0080C000,
  322.   0x0C000000,0x01030000,0x0C000000,0x021C0000,0x0C000000,0x01080000,
  323.   0x0C000000,0x00F00000,0x0C000000,0x01080000,0x0C000000,0x01080000,
  324.   0x0C004000,0x00F00000,0x0C001000,0x00000000,0x0C000400,0x00000000,
  325.   0x0C0001FF,0xFFFFFFFF,0xFC000000,0x00000000,0x0000FFFF,0xFFFFFFF8,
  326.   0x0000D555,0x55555556,0x0000D555,0x50005555,0x8000D555,0x47FF9555,
  327.   0x6000D555,0x5F03E555,0x5000D555,0x3E55F555,0x5000D555,0x3F55F555,
  328.   0x5000D555,0x3F55F555,0x5000D555,0x5E53F555,0x5000D555,0x4147E555,
  329.   0x5000D555,0x551FD555,0x5000D555,0x557F1555,0x5000D555,0x54FC5555,
  330.   0x5000D555,0x55E15555,0x5000D555,0x54F55555,0x5000D555,0x55055555,
  331.   0x5000D555,0x54F55555,0x5000D555,0x54F55555,0x50003555,0x55055555,
  332.   0x50000D55,0x55555555,0x50000355,0x55555555,0x50000000,0x00000000,
  333.   0x00000000,0x00000000,0x00000000,0x00145359,0x533A5072,0x6566732F,
  334.   0x58706B4D,0x61737465,0x72000000,0x00080000,0x000B4143,0x54494F4E,
  335.   0x3D555345,0x00000000,
  336. };
  337.  
  338. /* -------------------------- central functions ------------------------ */
  339.  
  340. void wbmain(struct WBStartup *wb)
  341. {
  342.   struct Args args = {0, 0, 0, 0, 0, 0};
  343.  
  344.   if(wb->sm_NumArgs > 2 || !wb->sm_NumArgs)
  345.     End(RETURN_FAIL);
  346.  
  347.   lock = CurrentDir(wb->sm_ArgList[wb->sm_NumArgs-1].wa_Lock);
  348.  
  349.   if((IconBase = OpenLibrary("icon.library", 37)) &&
  350.   (diskobject = GetDiskObject(wb->sm_ArgList[wb->sm_NumArgs-1].wa_Name)))
  351.   {
  352.     STRPTR a, *c = (STRPTR *) diskobject->do_ToolTypes;
  353.  
  354.     if(wb->sm_NumArgs == 2)
  355.       args.from = wb->sm_ArgList[1].wa_Name;
  356.  
  357.     args.edit = (ULONG) FindToolType(c, toolt[0]);
  358.     args.use = (ULONG) FindToolType(c, toolt[1]);
  359.     args.save = (ULONG) FindToolType(c, toolt[2]);
  360.     args.pubscreen = FindToolType(c, toolt[3]);
  361.     if((a = FindToolType(c, toolt[4])))
  362.     {
  363.       if(MatchToolValue(a, "YES"))
  364.         args.createicons = 1;
  365.     }
  366.     if((a = FindToolType(c, toolt[5])))
  367.     {
  368.       if(MatchToolValue(toolt[0], a))
  369.         args.edit = 1;
  370.       else if(MatchToolValue(toolt[1], a))
  371.         args.use = 1;
  372.       else if(MatchToolValue(toolt[2], a))
  373.         args.save = 1;
  374.     }
  375.   }
  376.  
  377.   Work(&args);
  378.   End(RETURN_OK);
  379. }
  380.  
  381. #ifdef __MAXON__
  382. void main(void)
  383. #else
  384. void main(int argc, char **argv)
  385. #endif
  386. {
  387.   struct Args args = {0, 0, 0, 0, 0, 0};
  388.  
  389. #ifdef __SASC
  390.   TestOS;
  391.   if(!argc)
  392.     wbmain((struct WBStartup *) argv);
  393. #endif
  394.  
  395.   if(!(rda = ReadArgs(PARAM, (LONG *) &args, 0)))
  396.     End(RETURN_FAIL);
  397.  
  398.   Work(&args);
  399.   End(RETURN_OK);
  400. }
  401.  
  402. void Work(struct Args *args)
  403. {
  404.   struct IntuiMessage *IntuiMessagePtr;
  405.   ULONG run = 1;
  406.   LONG Long;
  407.   STRPTR txt;
  408.  
  409.   if(args->edit)
  410.     args->use = args->save = 0;
  411.   if(args->save)
  412.     args->use = 0;
  413.  
  414.   if(
  415.   !(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37)) ||
  416.   !(GadToolsBase = OpenLibrary("gadtools.library", 37)) ||
  417.   !(UtilityBase = OpenLibrary("utility.library", 37)) ||
  418.   !(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",37)))
  419.     End(RETURN_FAIL);
  420.  
  421.   SDI_InitLocale(&locdat);
  422.   SDI_LocaleStrings(&locdat, initloc, text);
  423.   SDI_LocaleNewMenu(NewMenus, text + TEXT_START_MENUMAIN,
  424.     text + TEXT_START_OTHER);
  425.  
  426.   if(!(IFFParseBase = OpenLibrary("iffparse.library", 37)))
  427.   {
  428.     PrintError(text[TEXT_LIB_REQUIRED], "iffparse.library", 37);
  429.     End(RETURN_FAIL);
  430.   }
  431.  
  432.   NewPackerList(&maindata);
  433.  
  434.   if(args->use || args->save)
  435.   {
  436.     if(!args->from)
  437.       args->from = "";
  438.     if(LoadFile(args->from, 0) ||
  439.     (args->save && SaveFile((STRPTR)1 , 0)) ||
  440.     SaveFile(0, 0))
  441.       End(RETURN_FAIL);
  442.     End(RETURN_OK);
  443.   }
  444.  
  445.   if(args->createicons)
  446.     NewMenus[11].nm_Flags |= CHECKED;
  447.  
  448.   if(args->from && LoadFile(args->from, 0))
  449.     args->from = 0;
  450.  
  451.   if(!args->from && LoadFile(0, 0))
  452.     LoadFile((STRPTR) 1, 0);
  453.  
  454.   if(!(Scr = LockPubScreen(args->pubscreen)) ||
  455.   !(VisualInfo = GetVisualInfoA(Scr, 0)) ||
  456.   DoWindow())
  457.     End(RETURN_FAIL);
  458.  
  459.   do
  460.   {
  461.     if(Wait((1L<<window->UserPort->mp_SigBit)|SIGBREAKF_CTRL_C)
  462.     == SIGBREAKF_CTRL_C)
  463.       run = 0;
  464.     else
  465.       while(run && (IntuiMessagePtr = GT_GetIMsg(window->UserPort)))
  466.       {
  467.     switch(IntuiMessagePtr->Class)
  468.      {
  469.     case IDCMP_MENUPICK:
  470.       Long = (ULONG) IntuiMessagePtr->Code;
  471.       while(run && (ULONG) Long != MENUNULL)
  472.       {
  473.         switch(MENUNUM((ULONG) Long))
  474.         {
  475.         case 0:                    /* Projekt */
  476.           switch(ITEMNUM((ULONG) Long))
  477.           {
  478.           case 0:                    /* Open... */
  479.         if(PrefsFileReq(args->from, 0, text[TEXT_LOAD_PREFERENCES]))
  480.         {
  481.           args->from = namestring;
  482.           LoadFile(args->from, 0);
  483.                SetMainData();
  484.           ResetListView(0, &maindata);
  485.         }
  486.         break;
  487.           case 1:                    /* Load Add... */
  488.         if(PrefsFileReq(args->from, 0, text[TEXT_LOAD_PREFERENCES]))
  489.         {
  490.           args->from = namestring;
  491.           LoadFile(args->from, 1);
  492.               ResetListView(0, &maindata);
  493.         }
  494.         break;
  495.           case 2:                    /* Save As... */
  496.         if(PrefsFileReq(args->from, 1, text[TEXT_SAVE_PREFERENCES]))
  497.         {
  498.           args->from = namestring;
  499.           SaveFile(args->from, args->createicons);
  500.         }
  501.         break;
  502.           case 4: run = 0; break;            /* Quit */
  503.           } break;
  504.         case 1:                    /* Edit */
  505.           switch(ITEMNUM((ULONG) Long))
  506.           {
  507.           case 0:                /* Reset To Defaults */
  508.         NewPackerList(&maindata);
  509.         ResetListView(0, &maindata);
  510.         break;
  511.           case 1:                    /* Last Saved */
  512.         LoadFile((STRPTR) 1, 0);
  513.         SetMainData();
  514.             ResetListView(0, &maindata);
  515.         break;
  516.           case 2:                    /* Restore */
  517.         LoadFile(0, 0);
  518.             SetMainData();
  519.         ResetListView(0, &maindata);
  520.         break;
  521.           } break;
  522.         case 2:                    /* Settings */
  523.           args->createicons =
  524.           ItemAddress(menus, (ULONG) Long)->Flags & CHECKED;
  525.           break;
  526.         }
  527.         Long = (ULONG) ItemAddress(menus, (ULONG) Long)->NextSelect;
  528.       } break;
  529.     case IDCMP_GADGETUP:
  530.       switch(GADGET(IntuiMessagePtr)->GadgetID)
  531.       {
  532.       case STRING_TypeName:
  533.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  534.         FreeListView();
  535.         CopyMem(txt, maindata.ld_curNode->pn_TypeName, TypeSIZE);
  536.         ResetListView(~0, &maindata);
  537.         break;
  538.       case LISTVIEW: ResetListView(IntuiMessagePtr->Code, &maindata); break;
  539.       case BUTTON_New:
  540.         FreeListView();
  541.         if(!NewPackerNode(&maindata, text[TEXT_ENTRY_NEW],
  542.         DEFNODE(&maindata), maindata.ld_curNumber))
  543.           End(RETURN_FAIL);
  544.         ResetListView(~0, &maindata); break;
  545.       case BUTTON_Delete:
  546.         if(maindata.ld_curNumber)
  547.         {
  548.           FreeListView();
  549.           Remove((struct Node *) maindata.ld_curNode);
  550.           FreeMem(maindata.ld_curNode, sizeof(struct PackerNode));
  551.           if(--maindata.ld_entries == maindata.ld_curNumber)
  552.             --maindata.ld_curNumber;
  553.           ResetListView(~0, &maindata);
  554.         } break;
  555.       case BUTTON_Up:
  556.         if(maindata.ld_curNumber > 1)
  557.         {
  558.           struct Node *p;
  559.           FreeListView();
  560.           p = maindata.ld_curNode->pn_Node.ln_Pred->ln_Pred;
  561.           Remove((struct Node *) maindata.ld_curNode);
  562.           Insert(&maindata.ld_List, (struct Node *) maindata.ld_curNode, p);
  563.           ResetListView(--maindata.ld_curNumber, &maindata);
  564.         } break;
  565.       case BUTTON_Down:
  566.         if(maindata.ld_curNumber &&
  567.         maindata.ld_curNumber != maindata.ld_entries - 1)
  568.         {
  569.           struct Node *p;
  570.           FreeListView();
  571.           p = maindata.ld_curNode->pn_Node.ln_Succ;
  572.           Remove((struct Node *) maindata.ld_curNode);
  573.           Insert(&maindata.ld_List, (struct Node *) maindata.ld_curNode, p);
  574.           ResetListView(++maindata.ld_curNumber, &maindata);
  575.         } break;
  576.       case STRING_NamePatt:
  577.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  578. /* add test for correct pattern here */
  579.         CopyMem(txt, &maindata.ld_curNode->pn_NamePattern, NamePattSIZE);
  580.         break;
  581.       case STRING_FilePatt:
  582.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  583. /* add test for correct pattern here */
  584.         CopyMem(txt, &maindata.ld_curNode->pn_FilePattern, FilePattSIZE);
  585.         break;
  586.       case GETIMAGE: FileReq(); GT_SetGadgetAttrs(gadgdata[3], window,
  587.         0, GTST_String, &maindata.ld_curNode->pn_StdID, GA_Disabled,
  588.         maindata.ld_curNode->pn_Cycle, TAG_DONE);
  589.         break;
  590.       case STRING_LibraryName:
  591.         txt = STRINF(GADGET(IntuiMessagePtr))->Buffer;
  592.         if((Long = SDIConvToUpper(txt)))
  593.         {
  594.           maindata.ld_curNode->pn_StdID = Long;
  595.           GT_SetGadgetAttrs(gadgdata[3], window,
  596.           0, GTST_String, &maindata.ld_curNode->pn_StdID, GA_Disabled,
  597.           maindata.ld_curNode->pn_Cycle, TAG_DONE);
  598.         }
  599.         else
  600.         {
  601.           DisplayBeep(Scr);
  602.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  603.         }
  604.         break;
  605.       case INTEGER_Mode:
  606.         Long = STRINF(GADGET(IntuiMessagePtr))->LongInt;
  607.         if((Long > 100) || (Long < 0))
  608.         {
  609.           DisplayBeep(Scr);
  610.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  611.         }
  612.         else maindata.ld_curNode->pn_Mode = Long;
  613.         break;
  614.       case INTEGER_ChunkSize:
  615.         Long = STRINF(GADGET(IntuiMessagePtr))->LongInt;
  616.         if(Long < 0)
  617.         {
  618.           DisplayBeep(Scr);
  619.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  620.         }
  621.         else maindata.ld_curNode->pn_ChunkSize = Long;
  622.         break;
  623.       case CYCLE: maindata.ld_curNode->pn_Cycle = IntuiMessagePtr->Code;
  624.         ResetListView(~0, &maindata); break;
  625.       case INTEGER_TimeOut:
  626.         Long = STRINF(GADGET(IntuiMessagePtr))->LongInt;
  627.         if(Long < 0 || Long > 0xFFFF)
  628.         {
  629.           DisplayBeep(Scr);
  630.           ActivateGadget(GADGET(IntuiMessagePtr), window,0);
  631.         }
  632.         else TimeOut = Long;
  633.         break;
  634.       case CHECKBOX_XFD:
  635.         XPKM_Flags ^= XPKM_UseXFD; break;
  636.       case CHECKBOX_EXT:
  637.         XPKM_Flags ^= XPKM_UseExternals; break;
  638.       case CHECKBOX_Password:
  639.         XPKM_Flags ^= XPKM_AutoPassword; break;
  640.       case BUTTON_Save:
  641.         if(!SaveFile((STRPTR) 1, 0))
  642.           if(!SaveFile(0, 0))
  643.         run = 0;
  644.          break;
  645.       case BUTTON_Use: if(!SaveFile(0, 0)) run = 0; break;
  646.       case BUTTON_Chancel: run = 0; break;
  647.       } break;
  648.     }
  649.         GT_ReplyIMsg(IntuiMessagePtr);
  650.       }
  651.   }
  652.   while(run);
  653. }
  654.  
  655. ULONG SDIConvToUpper(STRPTR b)
  656. {
  657.   ULONG i;
  658.   ULONG out = 0;
  659.  
  660.   for(i = 0; i < 4; ++i)
  661.   {
  662.     if(!SDI_isalnum(b[i]))
  663.       return 0;
  664.     out = (out<<8) + SDI_toupper(b[i]);
  665.   }
  666.  
  667.   return out;
  668. }
  669.  
  670. /* ----------------------- loading functions --------------------------- */
  671.  
  672. void CorrectAdr(APTR pos, APTR mempos)
  673. { /* changes relative addresses into normal ones */
  674.   if(*(ULONG *)pos)
  675.     *(ULONG *)pos += (ULONG) mempos;
  676. }
  677.  
  678. void CopyStrings(STRPTR from, STRPTR to, ULONG Size)
  679. {
  680.   ULONG i;
  681.  
  682.   if(from)
  683.   {
  684.     if((i = SDI_strlen(from)) > Size)
  685.       i = Size;
  686.     CopyMem(from, to, i);
  687.   }
  688. }
  689.  
  690. void CopyLibName(struct XpkTypeData *p, struct PackerNode *n)
  691. {
  692.   if(p->xtd_Flags & XTD_NoPack)
  693.     n->pn_Cycle = 1;
  694.   else if(p->xtd_Flags & XTD_ReturnError || !p->xtd_StdID)
  695.     n->pn_Cycle = 2;
  696.   else
  697.   {
  698.     n->pn_Cycle = 0;
  699.     n->pn_StdID = p->xtd_StdID;
  700.   }
  701. }
  702.  
  703. void ReadXPKM(struct XpkMainPrefs *pref, struct ListData *dat)
  704. {
  705.   struct PackerNode *n = DEFNODE(dat);
  706.   struct XpkTypeData *p;
  707.  
  708.   CorrectAdr(&pref->xmp_DefaultType, pref);
  709.   p = pref->xmp_DefaultType;
  710.   CopyLibName(p, n);
  711.   n->pn_Mode = p->xtd_Mode;
  712.   n->pn_ChunkSize = p->xtd_ChunkSize;
  713.   TimeOut = pref->xmp_Timeout;
  714.   XPKM_Flags = pref->xmp_Flags;
  715. }
  716.  
  717. ULONG ReadXPKT(struct XpkTypePrefs *pref, struct ListData *dat)
  718. {
  719.   struct PackerNode *n;
  720.  
  721.   CorrectAdr(&pref->xtp_NamePattern, pref);
  722.   CorrectAdr(&pref->xtp_FilePattern, pref);
  723.   CorrectAdr(&pref->xtp_TypeName, pref);
  724.   CorrectAdr(&pref->xtp_PackerData, pref);
  725.   if(!pref->xtp_TypeName)
  726.     pref->xtp_TypeName = text[TEXT_ENTRY_NEW];
  727.  
  728.   if(!(n = NewPackerNode(dat, pref->xtp_TypeName, 0, dat->ld_curNumber)))
  729.     return 2;
  730.  
  731.   CopyStrings(pref->xtp_NamePattern, n->pn_NamePattern, NamePattSIZE);
  732.   CopyStrings(pref->xtp_FilePattern, n->pn_FilePattern, FilePattSIZE);
  733.   CopyLibName(pref->xtp_PackerData, n);
  734.   n->pn_Mode = pref->xtp_PackerData->xtd_Mode;
  735.   n->pn_ChunkSize = pref->xtp_PackerData->xtd_ChunkSize;
  736.   return 0;
  737. }
  738.  
  739. ULONG LoadFile(STRPTR file, ULONG addmode)
  740. {
  741. /* addmode only processes PRHD and XPKT chunks (not XPKM) -- adds the
  742.    chunks to the list -- no replacement */
  743.  
  744.   struct ContextNode  *cn;
  745.   struct IFFHandle *iff;
  746.   ULONG data = (ULONG) file > 1 ? 1 : 0;
  747.   ULONG error = 0;
  748.  
  749.   if(file == (STRPTR) 1)
  750.     file = "ENVARC:xpkmaster.prefs";
  751.   else if(!file)
  752.     file = "ENV:xpkmaster.prefs";
  753.  
  754.   if((iff = AllocIFF()))
  755.   {
  756.     if((iff->iff_Stream = Open(file, MODE_OLDFILE)))
  757.     {
  758.       InitIFFasDOS(iff);
  759.       if(!(error = OpenIFF(iff, IFFF_READ)))
  760.       {
  761.     LONG a[] = { ID_PREF, ID_PRHD, ID_PREF, ID_XPKT, ID_PREF, ID_XPKM};
  762.     if(!(error = StopChunks(iff, a, 3)))
  763.     {
  764.       STRPTR buf;
  765.       ULONG Flags = (addmode ? 2 : 0);
  766.  
  767.       while(!error)
  768.           {
  769.             if((error = ParseIFF(iff,IFFPARSE_SCAN)))
  770.               break;
  771.  
  772.             cn = CurrentChunk(iff);
  773.  
  774.         if(!addmode && cn->cn_ID != ID_PRHD)
  775.         {    /* clear list only when XPKT or XPKM and not addmode */
  776.           NewPackerList(&maindata); addmode = 1;
  777.         }
  778.  
  779.         if((buf = (STRPTR) AllocMem(cn->cn_Size, MEMF_ANY|MEMF_CLEAR)))
  780.         {
  781.           ReadChunkBytes(iff,buf,cn->cn_Size);
  782.           switch(cn->cn_ID)
  783.           {
  784.           case ID_PRHD:
  785.         if(!(Flags & 1))
  786.         {
  787.           if(((struct PrefHeader *) buf)->ph_Version > PREF_VERSION)
  788.             PrintError(text[TEXT_VERSION_TO_HIGH]);
  789.           Flags |= 1;
  790.         } break;
  791.           case ID_XPKM:
  792.         if(!(Flags & 2))
  793.         {
  794.           ReadXPKM((struct XpkMainPrefs *) buf, &maindata);
  795.           Flags |= 2;
  796.         } break;
  797.           case ID_XPKT:
  798.         error = ReadXPKT((struct XpkTypePrefs *) buf, &maindata);
  799.         break;
  800.           }
  801.           FreeMem(buf, cn->cn_Size);
  802.         }
  803.         else error = 2;
  804.       }
  805.       if(error == IFFERR_EOF)
  806.         error = 0;
  807.     }
  808.         CloseIFF(iff);
  809.       }
  810.       Close(iff->iff_Stream);
  811.     }
  812.     else if(data)
  813.     {
  814.       UBYTE err[100];
  815.       Fault(IoErr(), 0, err, 100);
  816.       PrintError(text[TEXT_ERROR_FILEACCESS], file, &err);
  817.       error = 1;
  818.     }
  819.     else
  820.       error = 1;
  821.     FreeIFF(iff);
  822.   }
  823.  
  824.   if(error && error != 1)
  825.     PrintError(text[TEXT_ERROR_FILEPROCESS]);
  826.  
  827.   return error;
  828. }
  829.  
  830. /* ----------------------- saving functions ---------------------------- */
  831.  
  832. ULONG CopyData(STRPTR from, ULONG *to, APTR data, STRPTR *entry)
  833. {
  834.   ULONG i = SDI_strlen(from);
  835.  
  836.   if(!(*from))
  837.     return 0;
  838.   CopyMem(from, (STRPTR) data + *to, i);
  839.   *entry = (STRPTR) *to;
  840.   *to += ++i;
  841. }
  842.  
  843. #define XPKM_Size    (sizeof(struct XpkMainPrefs) + \
  844.             sizeof(struct XpkTypeData))
  845.  
  846. #define    xpkm    ((struct XpkMainPrefs *) data)
  847. #define xpkd    ((struct XpkTypeData *) (data + sizeof(struct XpkMainPrefs)))
  848.  
  849. ULONG WriteXPKM(struct IFFHandle *iff)
  850. {
  851.   STRPTR data;
  852.   struct PackerNode *r = DEFNODE(&maindata);
  853.   ULONG ptr = sizeof(struct XpkMainPrefs), error;
  854.  
  855.   if(!r->pn_Cycle && !r->pn_StdID)
  856.   {
  857.     PrintError(text[TEXT_ILLEGAL_ENTRY], text[GADG_Library_Name], 1, r->pn_TypeName);
  858.     return 1;
  859.   }
  860.  
  861.   if((data = (STRPTR) AllocMem(XPKM_Size, MEMF_ANY|MEMF_CLEAR)))
  862.   {
  863. //    xpkm->xmp_Version        = 0;    /* structure version */
  864.     xpkm->xmp_Flags        = XPKM_Flags;
  865.     xpkm->xmp_Timeout        = TimeOut;
  866.     xpkm->xmp_DefaultType    = (struct XpkTypeData *) ptr;
  867.     ptr += sizeof(struct XpkTypeData);
  868.  
  869.     switch(r->pn_Cycle)
  870.     {
  871.     case 0:
  872.       xpkd->xtd_Mode = r->pn_Mode;
  873.       xpkd->xtd_ChunkSize = r->pn_ChunkSize;
  874.       xpkd->xtd_StdID = r->pn_StdID;
  875.       break;
  876.     case 1: xpkd->xtd_Flags |= XTD_NoPack; break;
  877.     case 2: xpkd->xtd_Flags |= XTD_ReturnError; break;
  878.     }
  879.  
  880.     if(!(error = PushChunk(iff, 0, ID_XPKM, ptr)))
  881.     {
  882.       if(WriteChunkBytes(iff, data, ptr) != ptr)
  883.     error = 3;
  884.       else
  885.     error = PopChunk(iff);
  886.     }
  887.     FreeMem(data, XPKM_Size);
  888.   }
  889.   else
  890.     error = 2;
  891.  
  892.   return error;
  893. }
  894.  
  895. #define xpkt        ((struct XpkTypePrefs *) data)
  896. #define xtd        ((struct XpkTypeData *) (data + sizeof(struct XpkTypePrefs)))
  897.  
  898. #define XPKT_Size    (TypeSIZE + 1 + NamePattSIZE + 1 + \
  899.             FilePattSIZE + 1 + sizeof(struct XpkTypePrefs)) \
  900.             + sizeof(struct XpkTypeData)
  901.  
  902. ULONG WriteXPKT(struct IFFHandle *iff, struct PackerNode *r, ULONG num)
  903. {
  904.   STRPTR data;
  905.   ULONG error, ptr = sizeof(struct XpkTypePrefs) + sizeof(struct XpkTypeData);
  906.  
  907.   if(!r->pn_Cycle && !r->pn_StdID)
  908.   {
  909.     PrintError(text[TEXT_ILLEGAL_ENTRY], text[GADG_Library_Name], num+1, r->pn_TypeName);
  910.     return 1;
  911.   }
  912.   else if(!r->pn_NamePattern[0] && !r->pn_FilePattern[0])
  913.   {
  914.     PrintError(text[TEXT_ILLEGAL_ENTRY], text[GADG_File_Pattern], num+1, r->pn_TypeName);
  915.     return 1;
  916.   }
  917.  
  918.   if((data = (STRPTR) AllocMem(XPKT_Size, MEMF_ANY|MEMF_CLEAR)))
  919.   {
  920.     if(CopyData(r->pn_NamePattern, &ptr, data, &xpkt->xtp_NamePattern))
  921.       xpkt->xtp_Flags |= XPKT_NamePattern;
  922.     if(CopyData(r->pn_FilePattern, &ptr, data, &xpkt->xtp_FilePattern))
  923.       xpkt->xtp_Flags |= XPKT_FilePattern;
  924.     CopyData(r->pn_TypeName, &ptr, data, &xpkt->xtp_TypeName);
  925.     xpkt->xtp_PackerData = (struct XpkTypeData *) sizeof(struct XpkTypePrefs);
  926.  
  927.     switch(r->pn_Cycle)
  928.     {
  929.     case 0:
  930.       xtd->xtd_Mode = r->pn_Mode;
  931.       xtd->xtd_ChunkSize = r->pn_ChunkSize;
  932.       xtd->xtd_StdID = r->pn_StdID;
  933.       break;
  934.     case 1: xtd->xtd_Flags |= XTD_NoPack; break;
  935.     case 2: xtd->xtd_Flags |= XTD_ReturnError; break;
  936.     }
  937.  
  938.     if(!(error = PushChunk(iff, 0, ID_XPKT, ptr)))
  939.     {
  940.       if(WriteChunkBytes(iff, data, ptr) != ptr)
  941.     error = 3;
  942.       else
  943.     error = PopChunk(iff);
  944.     }
  945.     FreeMem(data, XPKT_Size);
  946.   }
  947.   else
  948.     error = 2;
  949.  
  950.   return error;
  951. }
  952.  
  953. ULONG SaveFile(STRPTR file, ULONG icons)
  954. {
  955.   struct IFFHandle *iff;
  956.   ULONG error = 0;
  957.  
  958.   if(file == (STRPTR) 1)
  959.     file = "ENVARC:xpkmaster.prefs";
  960.   else if(!file)
  961.     file = "ENV:xpkmaster.prefs";
  962.  
  963.   if((iff = AllocIFF()))
  964.   {
  965.     if((iff->iff_Stream = Open(file, MODE_NEWFILE)))
  966.     {
  967.       InitIFFasDOS(iff);
  968.       if(!(error = OpenIFF(iff, IFFF_WRITE)))
  969.       {
  970.         if(!(error = PushChunk(iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN)))
  971.         {
  972.           if(!(error = PushChunk(iff, 0, ID_PRHD, sizeof(struct PrefHeader))))
  973.           {
  974.         struct PrefHeader a = {PREF_VERSION, 0, 0};
  975.         if(WriteChunkBytes(iff, &a, sizeof(struct PrefHeader))
  976.         == sizeof(struct PrefHeader))
  977.         {
  978.           if(!(error = PopChunk(iff)))
  979.           {
  980.             if(!(error = WriteXPKM(iff)))
  981.             {
  982.           struct Node *n = FindNode(&maindata.ld_List, 1);
  983.           ULONG num = 1, a;
  984.           for(a = maindata.ld_entries-1; a; --a)
  985.           {
  986.             if((error = WriteXPKT(iff, (struct PackerNode *) n, num)))
  987.               break;
  988.             n = n->ln_Succ; ++num;
  989.           }
  990.             }
  991.           }
  992.         }
  993.         else
  994.           error = 2;
  995.       }
  996.       if(!error)
  997.         error = PopChunk(iff);
  998.     }
  999.         CloseIFF(iff);
  1000.       }
  1001.       Close(iff->iff_Stream);
  1002.       if(error)
  1003.           DeleteFile(file);
  1004.     }
  1005.     else
  1006.     {
  1007.       UBYTE err[100];
  1008.       Fault(IoErr(), 0, err, 100);
  1009.       PrintError(text[TEXT_ERROR_FILEACCESS], file, &err);
  1010.       error = 1;
  1011.     }
  1012.     FreeIFF(iff);
  1013.   }
  1014.  
  1015.   if(!error && icons)
  1016.   {
  1017.     ULONG i = SDI_strlen(file);
  1018.     STRPTR a;
  1019.  
  1020.     if((a = (STRPTR) AllocMem(i+1+5, MEMF_ANY)))
  1021.     {
  1022.       ULONG fh;
  1023.  
  1024.       CopyMem(file, a, i);
  1025.       CopyMem(".info", a+i, 6);
  1026.       if((fh = Open(a, MODE_NEWFILE)))
  1027.       {
  1028.     Write(fh, PicData, PicSize);
  1029.     Close(fh);
  1030.       }
  1031.       FreeMem(a, i+1+5);
  1032.     }
  1033.   }
  1034.  
  1035.   if(error && error != 1)
  1036.     PrintError(text[TEXT_ERROR_FILEPROCESS]);
  1037.  
  1038.   return error;
  1039. }
  1040.  
  1041. /* ---------------------- graphics functions --------------------------- */
  1042.  
  1043. void PrintError(STRPTR txt, ...)
  1044. {
  1045.   struct EasyStruct easystruct;
  1046.  
  1047.   SDI_memset(&easystruct, 0, sizeof(struct EasyStruct));
  1048.  
  1049.   easystruct.es_StructSize = sizeof(struct EasyStruct);
  1050.   easystruct.es_Title = text[TEXT_TITLE_ERR_REQUEST];
  1051.   easystruct.es_TextFormat = txt;
  1052.   easystruct.es_GadgetFormat = text[GADGS_ERR_REQUEST];
  1053.  
  1054.   EasyRequestArgs(window, &easystruct, 0, (APTR)
  1055.   ((ULONG) &txt + sizeof(STRPTR)));
  1056. }
  1057.  
  1058. void FileReq(void)
  1059. {
  1060.   ULONG Long;
  1061.   UBYTE libname[] = "x..____.library";
  1062.   struct FileRequester *r;
  1063.  
  1064.   CopyMem(&maindata.ld_curNode->pn_StdID, libname+3, 4);
  1065.   if(libname[3] == 'X')
  1066.   {
  1067.     libname[1] = 'e'; libname[2] = 'x';
  1068.   }
  1069.   else
  1070.   {
  1071.     libname[1] = 'p'; libname[2] = 'k';
  1072.   }
  1073.  
  1074.   if((AslBase = OpenLibrary("asl.library", 37)))
  1075.   {
  1076.     if((r = (struct FileRequester *) AllocAslRequest(ASL_FileRequest, 0)))
  1077.     {
  1078.       if((AslRequestTags(r, ASLFR_TitleText, text[TEXT_SELECT_LIBRARY],
  1079.     ASLFR_InitialFile, libname,
  1080.     ASLFR_InitialDrawer, "LIBS:compressors", ASLFR_DoSaveMode, FALSE,
  1081.     ASLFR_InitialPattern, "(xpk|xex)????.library", TAG_DONE)))
  1082.         if((!SDI_strncmp(r->fr_File, "xpk", 3) ||
  1083.         !SDI_strncmp(r->fr_File, "xex", 3) &&
  1084.         !SDI_strcmp(r->fr_File+7, ".library")) &&
  1085.         (Long = SDIConvToUpper(r->fr_File+3)))
  1086.       maindata.ld_curNode->pn_StdID = Long;
  1087.     else
  1088.       DisplayBeep(Scr);
  1089.       FreeAslRequest(r);
  1090.     }
  1091.     CloseLibrary(AslBase);
  1092.     AslBase = 0;
  1093.   }
  1094.   else
  1095.     PrintError(text[TEXT_LIB_REQUIRED], "asl.library", 37);
  1096. }
  1097.  
  1098. ULONG PrefsFileReq(STRPTR dir, ULONG mode, STRPTR title)
  1099. {
  1100.   ULONG error = 0;
  1101.   struct FileRequester *r;
  1102.  
  1103.   if((AslBase = OpenLibrary("asl.library", 37)))
  1104.   {
  1105.     if((r = (struct FileRequester *) AllocAslRequest(ASL_FileRequest, 0)))
  1106.     {
  1107.       UBYTE d[200], *f = 0;
  1108.  
  1109.       if(dir)
  1110.       {
  1111.         CopyMem(dir, d, 200);
  1112.         if((f = FilePart(dir)))
  1113.         d[f-dir] = 0;
  1114.       }
  1115.       
  1116.       if((AslRequestTags(r, ASLFR_TitleText, title,
  1117.     ASLFR_InitialDrawer, dir ? d : "SYS:Prefs/Presets",
  1118.     ASLFR_DoSaveMode, mode,    (f ? ASLFR_InitialFile : TAG_DONE), f,
  1119.     TAG_DONE)))
  1120. /* only give ASLFR_InitialFile, when f is not zero, because else
  1121.    asl.library makes Enforcer hit! */
  1122.       {
  1123.         CopyMem(r->fr_Drawer, namestring, SDI_strlen(r->fr_Drawer)+1);
  1124.         AddPart(namestring, r->fr_File, 256);
  1125.         error = 1;
  1126.       }
  1127.       FreeAslRequest(r);
  1128.     }
  1129.     CloseLibrary(AslBase);
  1130.     AslBase = 0;
  1131.   }
  1132.   else
  1133.     PrintError(text[TEXT_LIB_REQUIRED], "asl.library", 37);
  1134.  
  1135.   return error;
  1136. }
  1137.  
  1138. void FreeListView(void)
  1139. {
  1140.   GT_SetGadgetAttrs(gadgdata[0], window, 0, GTLV_Labels, ~0, TAG_DONE);
  1141. }
  1142.  
  1143. void ResetListView(ULONG number, struct ListData *dat)
  1144. {
  1145.   STRPTR lib = "";
  1146.  
  1147.   if(number == ~0)
  1148.     number = dat->ld_curNumber;
  1149.   dat->ld_curNode = (struct PackerNode *) FindNode(&dat->ld_List, number);
  1150.  
  1151.   /* NamePattern */
  1152.   GT_SetGadgetAttrs(gadgdata[1], window, 0, GTST_String,
  1153.   dat->ld_curNode->pn_NamePattern, GA_Disabled, !number, TAG_DONE);
  1154.  
  1155.   /* FilePattern */
  1156.   GT_SetGadgetAttrs(gadgdata[2], window, 0, GTST_String,
  1157.   dat->ld_curNode->pn_FilePattern, GA_Disabled, !number, TAG_DONE);
  1158.  
  1159.   /* Cycle */
  1160.   GT_SetGadgetAttrs(gadgdata[7], window, 0, GTCY_Active,
  1161.   dat->ld_curNode->pn_Cycle, TAG_DONE);
  1162.  
  1163.   /* Listview */
  1164.   GT_SetGadgetAttrs(gadgdata[0], window, 0, GTLV_Labels, &dat->ld_List,
  1165.   GTLV_Selected, number, GTLV_Top, ((LONG) number - 5 < 0 ?
  1166.   0 : number - 5), TAG_DONE);
  1167.  
  1168.   if(dat->ld_curNode->pn_StdID)
  1169.     lib = (STRPTR) &dat->ld_curNode->pn_StdID;
  1170.  
  1171.   /* Name */
  1172.   GT_SetGadgetAttrs(gadgdata[3], window, 0, GTST_String,
  1173.   lib, GA_Disabled, dat->ld_curNode->pn_Cycle, TAG_DONE);
  1174.  
  1175.   /* GetImage */
  1176.   GT_SetGadgetAttrs(gadgdata[4], window, 0, GA_Disabled,
  1177.   dat->ld_curNode->pn_Cycle, TAG_DONE);
  1178.  
  1179.   /* Mode */
  1180.   GT_SetGadgetAttrs(gadgdata[5], window, 0, GTIN_Number,
  1181.   dat->ld_curNode->pn_Mode, GA_Disabled, dat->ld_curNode->pn_Cycle,
  1182.   TAG_DONE);
  1183.  
  1184.   /* ChunkSize */
  1185.   GT_SetGadgetAttrs(gadgdata[6], window, 0, GTIN_Number,
  1186.   dat->ld_curNode->pn_ChunkSize, GA_Disabled, dat->ld_curNode->pn_Cycle,
  1187.   TAG_DONE);
  1188.  
  1189.   dat->ld_curNumber = number;
  1190. }
  1191.  
  1192. void SetMainData(void)
  1193. {
  1194.   ULONG i;
  1195.  
  1196.   for(i = 0; i < 3; i++)
  1197.   {
  1198.     GT_SetGadgetAttrs(gadgdata[9+i], window, 0, GTCB_Checked,
  1199.     XPKM_Flags & (1<<i), TAG_DONE);
  1200.   }
  1201.   GT_SetGadgetAttrs(gadgdata[8], window, 0, GTIN_Number, TimeOut, TAG_DONE);
  1202. }
  1203.  
  1204. ULONG DoWindow(void)
  1205. {
  1206.   UWORD    winwidth, winheight;
  1207.   STRPTR *txt = text + GADG_New;
  1208.   ULONG i, j, k;
  1209.   struct Gadget        *g;
  1210.   struct NewGadget    ng;
  1211.  
  1212.   SDI_memset(&ng, 0, sizeof(struct NewGadget));
  1213.  
  1214.   ng.ng_LeftEdge = Scr->WBorLeft + SEPARATE_BORD;
  1215.   ng.ng_TopEdge = Scr->WBorTop + Scr->Font->ta_YSize + 1 + SEPARATE_BORD;
  1216.   ng.ng_Height = Scr->Font->ta_YSize+5;
  1217.   ng.ng_TextAttr = Scr->Font;
  1218.   ng.ng_GadgetID = 100;
  1219.   ng.ng_VisualInfo = VisualInfo;
  1220.  
  1221.   if(!(g = CreateContext(&gadgList)))
  1222.     return 1;
  1223.  
  1224.   for(i = k = 0; i < 4; ++i)
  1225.   {
  1226.     ng.ng_Width = 7 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1227.     if(ng.ng_Width > k)
  1228.       k = ng.ng_Width;
  1229.   }
  1230.   ng.ng_Width = k << 2;
  1231.  
  1232.   if(!(g = CreateGadget(STRING_KIND, g, &ng, GTST_MaxChars, TypeSIZE, TAG_DONE)))
  1233.     return 2;
  1234.   ++ng.ng_GadgetID;
  1235.  
  1236.   ng.ng_Height *= 10;
  1237.  
  1238.   if(!(gadgdata[0] = g = CreateGadget(LISTVIEW_KIND,g,&ng,
  1239.   GTLV_ShowSelected, g, TAG_DONE)))
  1240.     return 3;
  1241.  
  1242.   ++ng.ng_GadgetID;
  1243.   ng.ng_LeftEdge = Scr->WBorLeft + SEPARATE_BORD;
  1244.   ng.ng_TopEdge += g->Height + Scr->Font->ta_YSize+5;
  1245.   ng.ng_Height = Scr->Font->ta_YSize+5;
  1246.   ng.ng_Flags = PLACETEXT_IN;
  1247.   ng.ng_Width = k;
  1248.  
  1249.   for(i = 0; i < 4; ++i)
  1250.   {
  1251.     ng.ng_GadgetText = *(txt++);
  1252.     if(!(g = CreateGadgetA(BUTTON_KIND, g, &ng, 0)))
  1253.       return 4;
  1254.     ++ng.ng_GadgetID;
  1255.     ng.ng_LeftEdge += ng.ng_Width;
  1256.   }
  1257.  
  1258.   winheight = ng.ng_TopEdge + ng.ng_Height + SEPARATE_DIFF;
  1259.  
  1260.   ng.ng_TopEdge = Scr->WBorTop + Scr->Font->ta_YSize + 1 + SEPARATE_BORD;
  1261.   txt = text + GADG_Name_Pattern;
  1262.  
  1263.   for(i = k = 0; i < 6; ++i)
  1264.   {
  1265.     j = 7 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1266.     if(j > k)
  1267.       k = j;
  1268.   }
  1269.  
  1270.   j = ng.ng_LeftEdge + SEPARATE_DIFF; /* store startpos */
  1271.   ng.ng_LeftEdge = j + k;
  1272.  
  1273.   ng.ng_Width = 0;
  1274.   for(i = 0; i < 3; ++i)
  1275.   {
  1276.     STRPTR *tx = text + TEXT_START_SLIDER;
  1277.     k = 50 + TextLength(&Scr->RastPort, tx[i], SDI_strlen(tx[i]));
  1278.     if(k > ng.ng_Width)
  1279.       ng.ng_Width = k;
  1280.   } /* width of gadgets is the one of the cycle gadget */
  1281.  
  1282.   ng.ng_Flags = PLACETEXT_LEFT;
  1283.   winwidth = ng.ng_LeftEdge + ng.ng_Width; /* set resulting window width */
  1284.  
  1285.   for(i = 0; i < 2; ++i)
  1286.   {
  1287.     ng.ng_GadgetText = *(txt++);
  1288.     if(!(gadgdata[i+1] = g = CreateGadget(STRING_KIND,g,&ng, GTST_MaxChars,
  1289.     (i ? FilePattSIZE : NamePattSIZE), TAG_DONE)))
  1290.       return 5;
  1291.     ++ng.ng_GadgetID;
  1292.     ng.ng_TopEdge += ng.ng_Height + SEPARATE_SAME;
  1293.   }
  1294.  
  1295.   ng.ng_Width -= ng.ng_Height;
  1296.   ng.ng_GadgetText = *(txt++);
  1297.   if(!(gadgdata[3] = g = CreateGadget(STRING_KIND,g,&ng, GTST_MaxChars, 4,
  1298.   STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE)))
  1299.     return 6;
  1300.   ++ng.ng_GadgetID;
  1301.   ng.ng_GadgetText = 0;
  1302.   k = ng.ng_Width;
  1303.   ng.ng_Width = ng.ng_Height;
  1304.   ng.ng_LeftEdge += k;
  1305.   if(!(gadgdata[4] = g = CreateGadgetA(BUTTON_KIND,g,&ng, 0)))
  1306.     return 7;
  1307.   ng.ng_LeftEdge -= k;
  1308.   ng.ng_Width += k;
  1309.   ++ng.ng_GadgetID;
  1310.   ng.ng_TopEdge += ng.ng_Height + SEPARATE_SAME;
  1311.  
  1312.   for(i = 0; i < 2; ++i)
  1313.   {
  1314.     ng.ng_GadgetText = *(txt++);
  1315.     if(!(gadgdata[i+5] = g = CreateGadget(INTEGER_KIND,g,&ng, 
  1316.     STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE)))
  1317.       return 8;
  1318.     ++ng.ng_GadgetID;
  1319.     ng.ng_TopEdge += ng.ng_Height + SEPARATE_SAME;
  1320.   }
  1321.  
  1322.   ng.ng_GadgetText = *txt;
  1323.  
  1324.   if(!(gadgdata[7] = g = CreateGadget(CYCLE_KIND,g,&ng, GTCY_Labels,
  1325.   text + TEXT_START_SLIDER, TAG_DONE)))
  1326.       return 9;
  1327.  
  1328.   ++ng.ng_GadgetID;
  1329.   ng.ng_TopEdge += ng.ng_Height + SEPARATE_DIFF;
  1330.   txt = text + GADG_Use_XFD;
  1331.   ng.ng_LeftEdge = j;
  1332.  
  1333.   for(i = k = 0; i < 3; ++i)
  1334.   {
  1335.     ng.ng_Width = 50 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1336.     if(ng.ng_Width > k)
  1337.       k = ng.ng_Width;
  1338.   }
  1339.  
  1340.   ng.ng_GadgetText = txt[3];
  1341.   ng.ng_LeftEdge += k + ng.ng_Height;
  1342.   if((ng.ng_Width = 7 + TextLength(&Scr->RastPort, txt[3],
  1343.   SDI_strlen(txt[3]))) < Scr->RastPort.TxWidth << 3)
  1344.     ng.ng_Width = Scr->RastPort.TxWidth << 3;
  1345.   ng.ng_Flags = PLACETEXT_BELOW;
  1346.   if(!(gadgdata[8] = g = CreateGadget(INTEGER_KIND,g,&ng, GTIN_MaxChars, 5, STRINGA_Justification,
  1347.   GACT_STRINGCENTER, TAG_DONE)))
  1348.       return 10;
  1349.   ++ng.ng_GadgetID;
  1350.   ng.ng_LeftEdge -= k + ng.ng_Height;
  1351.   ng.ng_Width = ng.ng_Height;
  1352.   ng.ng_Flags = PLACETEXT_RIGHT;
  1353.  
  1354.   for(i = 0; i < 3; ++i)
  1355.   {
  1356.     ng.ng_GadgetText = *(txt++);
  1357.     if(!(gadgdata[9+i] = g = CreateGadgetA(CHECKBOX_KIND,g,&ng,0)))
  1358.       return 11;
  1359.     ++ng.ng_GadgetID;
  1360.     ng.ng_TopEdge += ng.ng_Height;
  1361.   }
  1362.  
  1363.   if(winheight < ng.ng_TopEdge + 5)
  1364.     winheight = ng.ng_TopEdge + SEPARATE_DIFF;
  1365.  
  1366.   ng.ng_TopEdge = winheight;
  1367.   ng.ng_LeftEdge = Scr->WBorLeft + SEPARATE_BORD;
  1368.   ng.ng_Flags = PLACETEXT_IN;
  1369.   txt = text + GADG_Save;
  1370.  
  1371.   ng.ng_Width = 0;
  1372.   for(i = 0; i < 3; ++i)
  1373.   {
  1374.     k = 7 + TextLength(&Scr->RastPort, txt[i], SDI_strlen(txt[i]));
  1375.     if(k >ng.ng_Width)
  1376.       ng.ng_Width = k;
  1377.   }
  1378.   k = (winwidth - SEPARATE_BORD - 3*ng.ng_Width)/6;
  1379.   ng.ng_LeftEdge += k;
  1380.  
  1381.   for(i = 0; i < 3; ++i)
  1382.   {
  1383.     ng.ng_GadgetText = *(txt++);
  1384.     if(!(g = CreateGadgetA(BUTTON_KIND, g, &ng, 0)))
  1385.       return 12;
  1386.     ++ng.ng_GadgetID;
  1387.     ng.ng_LeftEdge += ng.ng_Width + (k<<1);
  1388.   }  
  1389.  
  1390.   winwidth += Scr->WBorRight + SEPARATE_BORD;
  1391.   winheight += Scr->WBorBottom + ng.ng_Height + SEPARATE_BORD;
  1392.  
  1393.   if(winwidth > Scr->Width || winheight > Scr->Height)
  1394.   {
  1395.     PrintError(text[TEXT_NO_WINDOW],0);
  1396.     return 20;
  1397.   }
  1398.  
  1399.   if(!(menus = CreateMenusA(NewMenus, 0)))
  1400.     return 21;
  1401.  
  1402.   LayoutMenus(menus, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE);
  1403.  
  1404.   if(!(window = OpenWindowTags(0,
  1405.     WA_Top,        Scr->BarHeight + 1,
  1406.     WA_Width,    winwidth,
  1407.     WA_Height,    winheight,
  1408.     WA_IDCMP,    IDCMP_GADGETUP|IDCMP_MENUPICK|IDCMP_GADGETDOWN|
  1409.             IDCMP_MOUSEMOVE|IDCMP_INTUITICKS|IDCMP_MOUSEBUTTONS,
  1410.     WA_Flags,    WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SMART_REFRESH,
  1411.     WA_Gadgets,    gadgList,
  1412.     WA_Title,    text[TEXT_WINDOW_TITLE],
  1413.     WA_AutoAdjust,    TRUE,
  1414.         WA_Activate,    TRUE,
  1415.     WA_NewLookMenus,TRUE,
  1416.     WA_PubScreen,    Scr,
  1417.     TAG_DONE)))
  1418.     return 22;
  1419.  
  1420.   ResetListView(0, &maindata);
  1421.   SetMainData();
  1422.   SetMenuStrip(window, menus);
  1423.   GT_RefreshWindow(window,0);
  1424.   ScreenToFront(Scr);
  1425.  
  1426.   return 0;
  1427. }
  1428.  
  1429. /* --------------------------- list functions -------------------------- */
  1430.  
  1431. void NewPackerList(struct ListData *ld)
  1432. {
  1433.   if(ld->ld_entries)
  1434.     FreePackerList(ld);
  1435.   TimeOut = DEF_TIMEOUT; XPKM_Flags = DEF_XPKM_FLAGS;
  1436.   if(!NewPackerNode(&maindata, text[TEXT_ENTRY_DEFAULT], 0, 0))
  1437.     End(RETURN_FAIL);
  1438.   maindata.ld_curNode->pn_Cycle = DEF_CYCLE;
  1439. }
  1440.  
  1441. void FreePackerList(struct ListData *li)
  1442. {
  1443.   struct Node *n;
  1444.   while((n = RemHead(&li->ld_List)))
  1445.     FreeMem(n, sizeof(struct PackerNode));
  1446.   li->ld_curNumber = li->ld_entries = 0;
  1447.   li->ld_curNode = 0;
  1448. }
  1449.  
  1450. struct Node *FindNode(struct List *li, ULONG num)
  1451. {
  1452.   struct Node *n = li->lh_Head;
  1453.  
  1454.   ++num;
  1455.   if(n == (struct Node *) li)
  1456.     return 0;
  1457.   while(--num)
  1458.   {
  1459.     if(n == li->lh_TailPred)
  1460.       return 0;
  1461.     n = n->ln_Succ;
  1462.   }
  1463.   return n;
  1464. }
  1465.  
  1466. struct PackerNode *NewPackerNode(struct ListData *li, STRPTR name,
  1467. struct PackerNode *pref, ULONG mode)
  1468. {
  1469.   struct PackerNode *n;
  1470.   ULONG i;
  1471.  
  1472.   if(!(n = (struct PackerNode *) AllocMem(sizeof(struct PackerNode), MEMF_ANY|MEMF_CLEAR)))
  1473.     return 0;
  1474.  
  1475.   if(pref)
  1476.     CopyMem((STRPTR) pref + sizeof(struct Node), (STRPTR) n +
  1477.     sizeof(struct Node), sizeof(struct PackerNode) - sizeof(struct Node));
  1478.  
  1479.   n->pn_Node.ln_Name = n->pn_TypeName;
  1480.   n->pn_Node.ln_Type = mode ? PACKER_NODE : DEFAULT_NODE;
  1481.  
  1482.   if((i = SDI_strlen(name) + 1) > TypeSIZE)
  1483.     i = TypeSIZE;
  1484.   CopyMem(name, &n->pn_TypeName, i);
  1485.  
  1486.   if(li)
  1487.   {
  1488.     struct Node *p;
  1489.     if((p = FindNode(&li->ld_List, mode)))
  1490.     {
  1491.       Insert(&li->ld_List, (struct Node *) n, p);
  1492.       li->ld_curNumber = mode + 1;
  1493.     }
  1494.     else
  1495.     {
  1496.       AddTail(&li->ld_List, (struct Node *) n);
  1497.       li->ld_curNumber = li->ld_entries;
  1498.     }
  1499.     li->ld_curNode = n;
  1500.     ++li->ld_entries;
  1501.   }
  1502.  
  1503.   return (struct PackerNode *) n;
  1504. }
  1505.  
  1506. /* ---------------------- the cleanup stuff ---------------------------- */
  1507.  
  1508. void end(void)
  1509. {
  1510.   if(diskobject)    FreeDiskObject(diskobject);
  1511.   if(window)         CloseWindow(window);
  1512.   if(menus)        FreeMenus(menus);
  1513.   if(gadgList)        FreeGadgets(gadgList);
  1514.   if(VisualInfo)    FreeVisualInfo(VisualInfo);
  1515.   if(Scr)        UnlockPubScreen(0, Scr);
  1516.   if(GfxBase)        CloseLibrary((struct Library *) GfxBase);
  1517.   if(UtilityBase)    CloseLibrary(UtilityBase);
  1518.   if(GadToolsBase)    CloseLibrary(GadToolsBase);
  1519.   if(IntuitionBase)    CloseLibrary((struct Library *) IntuitionBase);
  1520.   if(IconBase)        CloseLibrary(IconBase);
  1521.   if(rda)        FreeArgs(rda);
  1522.   FreePackerList(&maindata);
  1523.   SDI_FreeLocale(&locdat);
  1524.   if(lock)        CurrentDir(lock);
  1525. }
  1526.  
  1527.